<?php
/**
 * XuYuan Project
 *
 * @package	XueYuan 
 * @author	Jiuchi Team
 * @since	Version 1.0.0
 * @filesource
 */
defined('BASEPATH') OR exit('No direct script access allowed');
/**
 * Model class
 * @author Wayne Yu
 */
class Jiuchi_Model extends CI_Model {
	public function __construct() {
		parent::__construct();
		$this->load->database();
	}
	
	/**
	 * Create entity and return the entity id
	 * @param array $data
	 * @return int id
	 */
	public function createEntity($data){
		$data['created_at'] = date('Y-m-d H:i:s', time());
		$res = $this->db->insert($this->table, $data);
		return $this->db->insert_id();
	}
	
	/**
	 * Mark the deleted field to delete the entity
	 * @param int $id
	 * @return boolean
	 */
	public function markDeleted($id){
		$this->db->where('id', $id);
		$res = $this->db->update($this->table, array('deleted'=>1));
		return $this->db->affected_rows();
	}
	
	/**
	 * Update the entity info
	 * @param int $id
	 * @param array $info
	 * @return boolean
	 */
	public function updateInfo($id, $info){
		$this->db->where('id', $id);
		$this->db->update($this->table, $info);
		return $this->db->affected_rows();
	}
	
	/**
	 * Get entity information by attribute(default ID)
	 * @param string $val :value in where condition
	 * @param string $attribute :field to select
	 * @return mixed
	 */
	public function getInfo($val, $attribute = 'id'){
		$query = $this->db->get_where($this->table, array($attribute => $val, 'deleted' => 0));
		$data = $query->row_array();
		if($data == NULL){
			return FALSE;
		}
		return $data;
	}
	
	/**
	 * Retrieve data from database
	 * @param int $count [NULL|>1]:Set count, [-1]:unset count, [1]:set count & return count
	 * @param int $limit [MULL]:un limit
	 * @param int $offset [NULL]:un offset
	 * @param string $select [NULL]:Select All
	 * @param array $where {} [NULL]: un where
	 * @param string $orderby [NULL] un order by
	 * @param string $direction ASC|DESC, [NULL]:undirection
	 * @param array $where_in {}|[{},...] [NULL]: un where in
	 * @param array $where_like {:key=>:val|[:match,:side],...} [NULL]: un where like
	 * @param array $or_where {} [NULL]: un or where
	 * @return array If $count === 1 return int
	 */
	public function retrieve(&$count = -1, $limit = NULL, $offset = NULL, $select = NULL, $where = NULL, $orderby = NULL, $direction = NULL, $where_in = NULL, $where_like = NULL, $or_where = NULL) {
		if (empty($count) OR $count !== -1) {
			if (!empty($where)) {
				if (is_array($where)) {
					foreach ($where as $key => $val) {
						$this->db->where($key, $val);
					}
				} else {
					$this->db->where($where);
				}
			}
			if (!empty($where_in)) {
				if (is_array($where_in)) {
					foreach ($where_in as $key => $val) {
						$this->db->where_in($key, $val);
					}
				}
			}
			if (!empty($where_like)) {
				if (is_array($where_like)) {
					foreach ($where_like as $key => $val) {
						if (is_array($val)) {
							$this->db->like($key, $val[0], $val[1]);
						} else {
							$this->db->like($key, $val);
						}
					}
				}
			}
			if ($count === 1) {
				$count = $this->db->count_all_results($this->table);
				return $count;
			}
			$count = $this->db->count_all_results($this->table);
			if ($count < 1) {
				return array();
			}
		}
		if (!empty($where)) {
			if (is_array($where)) {
				foreach ($where as $key => $val) {
					$this->db->where($key, $val);
				}
			} else {
				$this->db->where($where);
			}
		}
		if (!empty($or_where)) {
			if (is_array($or_where)) {
				foreach ($or_where as $key => $val) {
					$this->db->or_where($key, $val);
				}
			} else {
				$this->db->or_where($or_where);
			}
		}
		if (!empty($where_in)) {
			if (is_array($where_in)) {
				foreach ($where_in as $key => $val) {
					$this->db->where_in($key, $val);
				}
			}
		}
		if (!empty($where_like)) {
			if (is_array($where_like)) {
				foreach ($where_like as $key => $val) {
					if (is_array($val)) {
						$this->db->like($key, $val[0], $val[1]);
					} else {
						$this->db->like($key, $val);
					}
				}
			}
		}
		if (!empty($select)) {
			$this->db->select($select);
		}
		if (!empty($orderby) && !is_array($orderby)) {
			if (!empty($direction)) {
				$this->db->order_by($orderby, $direction);
			} else {
				$this->db->order_by($orderby);
			}
		} else if (is_array($orderby)) {
			foreach($orderby as $key => $val) {
				if (is_int($key)) {
					$this->db->order_by($val);
				} else {
					$this->db->order_by($key, $val);
				}
			}
		}
		if (!empty($limit)) {
			if (!empty($offset)) {
				$this->db->limit($limit, $offset);
			} else {
				$this->db->limit($limit);
			}
		}
		$command = $this->db->get($this->table);
		return $command->result_array();
	}
	
	/**
	 * Transaction begin
	 */
	public function begin() {
		$this->db->trans_begin();
	}
	
	/**
	 * Transaciton rollback
	 */
	public function rollback() {
		$this->db->trans_rollback();
	}
	
	/**
	 * Transaction commit
	 */
	public function commit() {
		$this->db->trans_commit();
	}
}